﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WorkflowTool
{
    public abstract class WorkflowBase
    {
        /// <summary>
        /// WorkflowTool名称
        /// </summary>
        public virtual string? Name { get; set; }
        private IWorflowContext? _context;
        protected WorkflowBase? _Workflownext;
        private WorflowOptions _worflowOptions;
        public WorkflowBase()
        {
            _worflowOptions = new WorflowOptions();
        }
        public WorkflowBase Next(WorkflowBase abstractBoss)
        {
            this._Workflownext = abstractBoss;
            return this;
        }
        /// <summary>
        /// WorkflowTool分支
        /// </summary>
        /// <param name="action"></param>
        /// <exception cref="Exception"></exception>
        public  void Map( Action<IWorflowContext> action)
        {
            if (_context == null)
            {
                throw new Exception("请先传入WorkflowTool，请确保Map在Start后调用");
            }
             action.Invoke(_context);
        }
        /// <summary>
        /// 开始行执行WorkflowTool
        /// </summary>
        /// <param name="context"></param>
        public  WorkflowBase Start(IWorflowContext context)
        {
            var startfiltering = _worflowOptions.filters.Where(w => typeof(IWorkflowFilter).IsAssignableFrom(w.GetType())).ToList();
            if (startfiltering.Count>0)
            {
                startfiltering.ForEach(f => {
                    f.GetType().GetMethod(nameof(f.OnWorkflowStartExecuting))?.Invoke(f, new object[] { context, _Workflownext,this });
                });
            }
            this._context = context;
            Console.WriteLine($"-------------{this.Name}");
            VAction(context,  () => {
                 if (_Workflownext != null)
                {
                     this._Workflownext._worflowOptions = _worflowOptions;
                     this._Workflownext?.Start(context);
                }
            });
            var startfiltered = _worflowOptions.filters.Where(w => typeof(IWorkflowFilter).IsAssignableFrom(w.GetType())).ToList();
            if (startfiltered.Count > 0)
            {
                startfiltered.ForEach(f => {
                    f.GetType().GetMethod(nameof(f.OnWorkflowStartExecuting))?.Invoke(f, new object[] { context, _Workflownext, this });
                });

            }
            return this;
        }
        public WorkflowBase AddFilters(Action<WorflowOptions> action)
        {
            action(_worflowOptions);
            return this;
        }
        /// <summary>
        /// 业务逻辑处理
        /// </summary>
        /// <param name="context">WorkflowTool</param>
        /// <param name="next">下一步</param>
        public abstract  void VAction(IWorflowContext context, Action next);
        /// <summary>
        /// 跳跃到某一步
        /// </summary>
        /// <param name="next"></param>
        public void JumpNext(WorkflowBase Workflownext, Action next)
        {
            Workflownext._context = _context;
            this.Next(Workflownext);
            next.Invoke();
        }
    }
}
